package com.citywithincity.models;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;

import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPFileFilter;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.io.CopyStreamEvent;
import org.apache.commons.net.io.CopyStreamListener;

import com.citywithincity.utils.IoUtil;

public class FtpModel {

	FTPClient ftpClient;
	private String server;
	private int port;
	private String userName;
	private String userPassword;
	private boolean debug;

	public FtpModel(String server, int port, String userName, String userPassword) {
		this.server = server;
		this.port = port;
		this.userName = userName;
		this.userPassword = userPassword;
	}
	
	public void setDebug(boolean debug){
		this.debug = debug;
	}

	private static CopyStreamListener createListener() {
		return new CopyStreamListener() {
			private long megsTotal = 0;

			// @Override
			public void bytesTransferred(CopyStreamEvent event) {
				bytesTransferred(event.getTotalBytesTransferred(), event.getBytesTransferred(), event.getStreamSize());
			}

			// @Override
			public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
				long megs = totalBytesTransferred / 1000000;
				for (long l = megsTotal; l < megs; l++) {
					System.err.print("#");
				}
				megsTotal = megs;
			}
		};
	}

	public boolean open() throws IOException {
		if (ftpClient != null && ftpClient.isConnected())
			return true;
		ftpClient = new FTPClient();
		if(debug){
			ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out), true));
			ftpClient.setCopyStreamListener(createListener());
		}
		ftpClient.connect(server, port);
		ftpClient.login(userName, userPassword);
		ftpClient.enterLocalPassiveMode();
		ftpClient.setDataTimeout(60000);       //设置传输超时时间为60秒 
		ftpClient.setConnectTimeout(60000);       //连接超时为60秒
		ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
		if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
			ftpClient.disconnect();
			return false;
		}
		return true;
	}
	
	/**
	 * 
	 * @param ftpFile
	 * @param dest
	 * @throws IOException
	 */
	public void retrieveFile(FTPFile ftpFile, File dest) throws IOException {
		OutputStream out =null;
		try{
			out = new FileOutputStream(dest);
			ftpClient.retrieveFile(ftpFile.getName(), out);
		}finally{
			IoUtil.close(out);
		}
	}
	public void retrieveFile(FTPFile ftpFile, OutputStream out) throws IOException {
		try{
			ftpClient.retrieveFile(ftpFile.getName(), out);
		}finally{
			IoUtil.close(out);
		}
	}
	public InputStream retrieveInputStream(FTPFile ftpFile) throws IOException{
		return ftpClient.retrieveFileStream(ftpFile.getName());
	}
	public InputStream retrieveInputStream(String name) throws IOException{
		return ftpClient.retrieveFileStream(name);
	}
	
	
	public void changeWorkingDirectory(String remotePath) throws IOException{
		ftpClient.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
	}
	
	public void sendFile(File file) throws IOException{
		FileInputStream stream = null;
		try {
			stream = new FileInputStream(file);
			String name = file.getName();
			ftpClient.storeFile(name, stream);
		}finally{
			IoUtil.close(stream);
		}
	}
	
	public void sendFile(String name,InputStream inputStream) throws IOException{
		try {
			ftpClient.storeFile(name, inputStream);
		}finally{
			IoUtil.close(inputStream);
		}
	}
	
	
	
	public FTPFile[] listFiles(String remotePath,FTPFileFilter filter) throws IOException {
		//FTPClientConfig config = new FTPClientConfig(FTPClientConfig.SYST_NT);
		//config.setLenientFutureDates(true);
		//ftpClient.configure(config);
		//ftpClient.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
		return ftpClient.listFiles(remotePath, filter);
	}

	public void close() {
		if (ftpClient != null) {
			try {
				ftpClient.logout();

			} catch (IOException e) {
			}
			try {
				ftpClient.disconnect();
			} catch (IOException e) {

			}
			ftpClient = null;
		}

	}

}
